package me.zhengjie.timing.plc;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import me.zhengjie.WcsReport.WcsReportService;
import me.zhengjie.agvSend.AgvSendService;
import me.zhengjie.pojo.dto.AgvTaskSubmitDto;
import me.zhengjie.pojo.dto.CarrierInfoDto;
import me.zhengjie.pojo.dto.ExtraDto;
import me.zhengjie.pojo.dto.TargetRoute;
import me.zhengjie.pojo.entity.WcsFluentFrameConfig;
import me.zhengjie.pojo.entity.WcsOutboundMission;
import me.zhengjie.pojo.vo.EmptyContainer;
import me.zhengjie.pojo.vo.ReturnVo;
import me.zhengjie.sqlservice.*;
import me.zhengjie.tcp.FluentFrame;
import me.zhengjie.utility.IdWorker;
import me.zhengjie.utility.liftState.PriorityEnum;
import me.zhengjie.utility.state.MaterialStatus;
import me.zhengjie.utility.state.TaskStatus;
import me.zhengjie.utility.state.TaskType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Component
@RequiredArgsConstructor
public class FluentFrameSingleLayerTiming {
    private static final Logger fluentFrameLog = LoggerFactory.getLogger("fluentFrame");

    private final WcsFluentFrameConfigService wcsFluentFrameConfigService;

//    private final FluentFrameTCPA fluentFrameTCPA;
//
//    private final FluentFrameTCPB fluentFrameTCPB;

    private final WcsReportService wcsReportService;

    private final WcsInboundMissionSqlService wcsInboundMissionService;

    private final AgvSendService agvSendService;

    private final WcsOutboundMissionService wcsOutboundMissionService;

    private final IdWorker idWorker;

    private final WcsFluentFrameOutboundDetailsService wcsFluentFrameOutboundDetailsService;

    private final WcsFluentFrameOutboundDetailsHistoryService wcsFluentFrameOutboundDetailsHistoryService;

    private final FluentFrame fluentFrame;

    @Transactional
    @Scheduled(fixedDelay = 1000)
    public void fluentFrameSingleLayer() {
        //查询所有流利架
        List<WcsFluentFrameConfig> wcsFluentFrameConfigList = wcsFluentFrameConfigService.selectSingLayer(1);
        if (!wcsFluentFrameConfigList.isEmpty()) {
            for (WcsFluentFrameConfig wcsFluentFrameConfig : wcsFluentFrameConfigList) {
                Integer id = wcsFluentFrameConfig.getId();
                Integer size = wcsFluentFrameConfig.getSize();
                String region = wcsFluentFrameConfig.getRegion();
                Integer outboundStorageSizeAddress = wcsFluentFrameConfig.getOutboundStorageSizeAddress();
                Integer unitId = wcsFluentFrameConfig.getUnitId();
                Integer threeOutReturnResult = wcsFluentFrameConfig.getThreeOutReturnResult();
                //查询流利架数量
                Integer quantity = fluentFrame.readHoldingRegisters(region,outboundStorageSizeAddress, unitId);
                fluentFrameLog.info("单层流利架配置:{},查询数量：{}", wcsFluentFrameConfig, quantity);
                if (quantity != null) {
                    //单层流利架
                    Integer storageSize = 4;
                    storageSize = storageSize - size - quantity;
                    if (storageSize >= 2) {
                        //单层流利架有二个储位时需要补空箱
                        for (Integer i = 0; i < storageSize; i++) {
                            //todo 发送空箱终点储位申请
                            String storageRegion = wcsFluentFrameConfig.getStorageRegion();
                            String destination = wcsFluentFrameConfig.getOutStorageCode();
                            ReturnVo returnVo = wcsReportService.emptyContainer(storageRegion);
                            fluentFrameLog.info("空箱出库起点储位申请结果：{}", returnVo);
                            if (returnVo.getCode() == 200) {
                                EmptyContainer emptyContainer = new ObjectMapper().convertValue(returnVo.getData(), EmptyContainer.class);
                                String outboundCode = String.valueOf(idWorker.nextId());
                                //容器编码
                                String containerCode = emptyContainer.getContainerCode();
                                //起点位置
                                String source = emptyContainer.getStorageCode();
                                String wmsTaskId = emptyContainer.getWmsTaskId();
                                List<WcsOutboundMission> wcsOutboundMissionList = wcsOutboundMissionService.selectContainerCodeNotTask(containerCode);
                                fluentFrameLog.info("查询出任务：{}",wcsOutboundMissionList);
                                if (!wcsOutboundMissionList.isEmpty()) {
                                    fluentFrameLog.info("出空箱，箱号：{},已在出库任务中",wcsOutboundMissionList);
                                    continue;
                                }

                                //000 0 0000
                                AgvTaskSubmitDto agvTaskSubmitDto = new AgvTaskSubmitDto();
                                //todo 任务类型，根据现场情况来定
                                agvTaskSubmitDto.setTaskType("CTU-KUNEI");
                                ArrayList<TargetRoute> targetRouteList = new ArrayList<>();
                                TargetRoute targetRoute = new TargetRoute();
                                TargetRoute targetRoutes = new TargetRoute();
                                //添加起点
                                targetRoute.setSeq(0);
                                targetRoute.setType(TaskType.STORAGE.getMessage());
                                targetRoute.setCode(source);
                                //添加终点
                                targetRoutes.setSeq(1);
                                targetRoutes.setType(TaskType.STORAGE.getMessage());
                                targetRoutes.setCode(destination);
                                targetRouteList.add(targetRoute);
                                targetRouteList.add(targetRoutes);
                                agvTaskSubmitDto.setTargetRoute(targetRouteList);
                                agvTaskSubmitDto.setRobotTaskCode(outboundCode);
                                agvTaskSubmitDto.setInitPriority(10);

                                CarrierInfoDto carrierInfoDto = new CarrierInfoDto();
                                carrierInfoDto.setCarrierCode(containerCode);
                                carrierInfoDto.setCarrierType(TaskType.TWO_Task_assignment_Container_binding.getMessage());
                                ArrayList<CarrierInfoDto> carrierInfoDtos = new ArrayList<>();
                                carrierInfoDtos.add(carrierInfoDto);
                                ExtraDto extraDto = new ExtraDto();
                                extraDto.setCarrierInfo(carrierInfoDtos);
                                agvTaskSubmitDto.setExtra(extraDto);
                                String taskCode = agvSendService.agvTaskSubmit(agvTaskSubmitDto);
                                //生成出空箱任务，发给AGV
                                if (taskCode != null) {
                                    //生成出库任务
                                    WcsOutboundMission wcsOutboundMission = new WcsOutboundMission();
                                    wcsOutboundMission.setOutboundCode(outboundCode);
                                    wcsOutboundMission.setMissionStatus(TaskStatus.task_send.getStatus());
                                    wcsOutboundMission.setContainerCode(containerCode);
                                    wcsOutboundMission.setSource(source);
                                    wcsOutboundMission.setDestination(destination);
                                    wcsOutboundMission.setCreateTime(LocalDateTime.now());
                                    wcsOutboundMission.setUpdateTime(LocalDateTime.now());
                                    wcsOutboundMission.setContainerType(TaskType.EMPTY_MATERIAL_BOX.getStatus());
                                    wcsOutboundMission.setPriority(90);
                                    wcsOutboundMission.setIsNest(0);
                                    wcsOutboundMission.setWmsTaskId(wmsTaskId);
                                    wcsOutboundMission.setFloor(TaskType.TWO_FLOOR.getMessage());
                                    wcsOutboundMission.setIsWms(1);
                                    boolean b = wcsOutboundMissionService.insertOutbound(wcsOutboundMission);
//                                    fluentFrame.writeWithRetry(threeOutReturnResult, MaterialStatus.AGV_TRANSPORT_IN_THE_TASK.getStatus(), unitId, MaterialStatus.RETRY_COUNT.getStatus(),region);
                                    //修改数量
                                    size++;
                                    wcsFluentFrameConfigService.updateSize(id, size);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
